<template>
  <div>
    <!-- 顶部搜索框 -->
    <el-card>
      <el-form :inline="true" class="form" @submit.prevent>
        <el-form-item label="职位搜索:">
          <el-input
            placeholder="请输入职位关键字"
            v-model="keyWord"
            @keyup.enter="getHasRole(1)"
          ></el-input>
        </el-form-item>
        <el-form-item>
          <el-button
            type="primary"
            size="default"
            :disabled="!keyWord"
            @click="getHasRole(1)"
            v-has="`btn.Role.assgin`"
          >
            搜索
          </el-button>
          <el-button type="info" size="default" @click="reset">重置</el-button>
        </el-form-item>
      </el-form>
    </el-card>
    <!-- 职位列表 -->
    <el-card style="margin-top: 10px" v-loading="loading">
      <el-button
        type="primary"
        icon="Plus"
        size="default"
        @click="addRole"
        v-has="`btn.Role.add`"
      >
        添加职位
      </el-button>
      <el-table :data="roleList" border stripe style="margin-top: 10px">
        <el-table-column
          label="#"
          align="center"
          type="index"
          width="80"
        ></el-table-column>
        <el-table-column
          prop="id"
          label="id"
          align="center"
          width="80"
        ></el-table-column>
        <el-table-column
          prop="roleName"
          label="角色名称"
          align="center"
        ></el-table-column>
        <el-table-column
          prop="createTime"
          label="创建时间"
          show-overflow-tooltip
          align="center"
        ></el-table-column>
        <el-table-column
          prop="updateTime"
          label="更新时间"
          show-overflow-tooltip
          align="center"
        ></el-table-column>
        <el-table-column label="操作" align="center" width="270">
          <template #default="{ row }">
            <el-button
              type="primary"
              icon="User"
              size="small"
              @click="setPermission(row)"
            >
              分配权限
            </el-button>
            <el-button
              type="warning"
              icon="Edit"
              size="small"
              @click="updateRole(row)"
              v-has="`btn.Role.update`"
            >
              编辑
            </el-button>
            <el-popconfirm
              confirm-button-text="确定"
              cancel-button-text="取消"
              icon="Delete"
              icon-color="red"
              :title="`你确定要删除&nbsp;${row.roleName}&nbsp;职位吗?`"
              @confirm="removeRole(row)"
              v-has="`btn.Role.remove`"
            >
              <template #reference>
                <el-button type="danger" icon="Delete" size="small">
                  删除
                </el-button>
              </template>
            </el-popconfirm>
          </template>
        </el-table-column>
      </el-table>
      <!-- 分页器 -->
      <template #footer>
        <el-pagination
          v-model:current-page="pageNo"
          v-model:page-size="pageSize"
          :page-sizes="[5, 10, 20]"
          :background="true"
          layout=" prev, pager, next, jumper,->, sizes,total"
          :total="total"
          @size-change="getHasRole(1)"
          @current-change="getHasRole"
        />
      </template>
    </el-card>
    <!-- 添加/修改职位对话框 -->
    <el-dialog
      v-model="dialogVisible"
      :title="role.id ? '修改职位' : '添加职位'"
      width="500"
      align-center
    >
      <el-form @submit.prevent ref="formRef" :model="role" :rules="rules">
        <el-form-item label="职位名称:" prop="roleName">
          <el-input
            placeholder="请输入职位名称"
            v-model.trim="role.roleName"
            @keyup.enter="saveRole"
          ></el-input>
        </el-form-item>
      </el-form>
      <template #footer>
        <div class="dialog-footer">
          <el-button @click="dialogVisible = false">取消</el-button>
          <el-button type="primary" @click="saveRole">确定</el-button>
        </div>
      </template>
    </el-dialog>
    <!-- 分配权限的抽屉对话框 -->
    <el-drawer v-model="drawerVisible" title="分配菜单与按钮权限">
      <!-- 树形控件 -->
      <el-tree
        v-loading="loading1"
        style="max-width: 600px"
        :data="menuList"
        node-key="id"
        show-checkbox
        accordion
        :default-checked-keys="selectArr"
        :props="defaultProps"
        ref="treeRef"
        check-on-click-node
      />
      <!-- 抽屉对话框底部内容 -->
      <template #footer>
        <el-button type="info" size="default" @click="drawerVisible = false">
          取消
        </el-button>
        <el-button type="primary" size="default" @click="savePermission">
          确定
        </el-button>
      </template>
    </el-drawer>
  </div>
</template>

<script setup lang="ts" name="Role">
import {
  reqAddOrUpdateRole,
  reqAllMenuList,
  reqAllRole,
  reqRemoveRole,
  reqSetPermission,
} from '@/api/acl/role'
import { MenuData, Role, RoleList } from '@/api/acl/role/type'
import { ElMessage } from 'element-plus'
import { onMounted, reactive, ref } from 'vue'

// 存储获取职位列表是否显示加载效果
let loading = ref(false)
// 存储获取权限菜单是否显示加载效果
let loading1 = ref(false)
// 存储当前页码
let pageNo = ref(1)
// 存储当前一页多少条
let pageSize = ref(5)
// 存储数据总条数
let total = ref(0)
// 存储职位列表
let roleList = ref<RoleList>([])
// 存储搜索关键字
let keyWord = ref('')
// 控制添加/修改职位对话框显示/隐藏
let dialogVisible = ref(false)
// 存储添加/更新的职位对象
let role = reactive<Role>({
  roleName: '',
})
// 获取添加/修改职位表单的ref
let formRef = ref()
// 控制是否展示抽屉对话框
let drawerVisible = ref(false)
// 存储权限菜单
let menuList = ref<MenuData[]>([])
// 存储已选四级权限的id数组
let selectArr = ref<number[]>([])
// 获取树形控件的ref
let treeRef = ref()

// 获取已有职位列表的方法
const getHasRole = async (pager = pageNo.value) => {
  // 修改当前的页码  不传参为当前页码
  pageNo.value = pager
  // 显示加载动画
  loading.value = true
  const result = await reqAllRole(pageNo.value, pageSize.value, keyWord.value)
  if (result.code === 200) {
    // 存储数据总条数
    total.value = result.data.total
    // 存储职位列表
    roleList.value = result.data.records
    // 关闭加载动画
    loading.value = false
  } else {
    ElMessage.error('获取职位列表失败')
  }
}
// 点击重置按钮的回调
const reset = () => {
  // 重置关键字为空
  keyWord.value = ''
  // 重新发请求获取第一页的数据
  getHasRole(1)
}
// 点击添加职位按钮的回调
const addRole = () => {
  // 清空上次表单校验提示
  formRef.value?.clearValidate() // 使用可选链?/nextTick(第一次获取不到formRef)
  // 清空上次收集的职位对象
  Object.assign(role, { id: undefined, roleName: '' })
  // 显示添加职位对话框
  dialogVisible.value = true
}
// 更新职位的回调
const updateRole = (row: Role) => {
  // 清空上次表单校验提示
  formRef.value?.clearValidate()
  // 获取当前职位信息
  Object.assign(role, row)
  // 显示对话框
  dialogVisible.value = true
}
// 添加/更新职位对话框确定按钮的回调
const saveRole = async () => {
  // 表单校验
  await formRef.value.validate()
  // 发请求
  const result = await reqAddOrUpdateRole(role)
  if (result.code == 200) {
    ElMessage.success(role.id ? '更新职位成功' : '添加职位成功')
    // 关闭对话框
    dialogVisible.value = false
    // 重新获取数据
    role.id ? getHasRole() : getHasRole(1)
  } else {
    ElMessage.error(role.id ? '更新职位失败' : '添加职位失败')
  }
}
// 职位名表单校验
const rules = {
  roleName: [
    { required: true, message: '职位名不能为空', trigger: 'blur' },
    { min: 2, message: '至少两个字符', trigger: 'blur' },
  ],
}
// 点击分配权限按钮的事件回调
const setPermission = async (row: Role) => {
  // 显示抽屉对话框
  drawerVisible.value = true
  // 显示加载效果
  loading1.value = true
  // 存储当前角色信息
  Object.assign(role, row)
  // 发请求获取权限菜单和已选的权限
  const result = await reqAllMenuList(row.id as number)
  if (result.code == 200) {
    // 存储返回的权限菜单数据
    menuList.value = result.data
    // 获取到已选的四级权限id数组
    selectArr.value = filterSelectArr(menuList.value, [])
    // 关闭加载效果
    loading1.value = false
  } else {
    ElMessage.error('获取数据失败')
  }
}
// 树形控件props配置选项
const defaultProps = {
  children: 'children',
  label: 'name',
}
// 过滤权限菜单第四级已选的id
const filterSelectArr = (allData: any, initArr: any) => {
  allData.forEach((item: any) => {
    if (item.children.length > 0) {
      // 当前权限有子权限时进行递归调用
      filterSelectArr(item.children, initArr)
    } else {
      // 当前权限没有子权限且为四级权限同时被选中时，添加到数组中
      if (item.select && item.level == 4) {
        initArr.push(item.id)
      }
    }
  })
  // 返回过滤到的四级已选全选的id数组
  return initArr
}
// 点击分配菜单权限确定按钮的回调
const savePermission = async () => {
  // 获取被选中权限的id和父级id
  let permissionId = treeRef.value
    .getCheckedKeys()
    .concat(treeRef.value.getHalfCheckedKeys())
  // 发请求  携带职位id和权限id数组
  const result = await reqSetPermission(role.id as number, permissionId)
  if (result.code === 200) {
    ElMessage.success('分配权限成功')
    // 关闭抽屉弹窗
    drawerVisible.value = false
    // 页面刷新
    window.location.reload()
  } else {
    ElMessage.error('分配权限失败')
  }
}
// 点击删除职位按钮的回调
const removeRole = async (row: Role) => {
  // 发请求
  const result = await reqRemoveRole(row.id as number)
  if (result.code == 200) {
    ElMessage.success('删除职位成功')
    // 重新获取职位数据
    getHasRole()
  } else {
    ElMessage.error('删除职位失败')
  }
}

// 组件挂载时获取职位列表进行展示
onMounted(() => {
  getHasRole()
})
</script>

<style scoped>
.form {
  display: flex;
  justify-content: space-between;
  align-items: center;
  height: 40px;
  padding-top: 15px;
}
</style>
